﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Xml;
using Microsoft.Win32;

namespace SHomeWorkshop.LunarPresentation.Commands
{
    public partial class Command
    {
        public static void OpenFile(MainWindow window,
            System.Windows.Controls.TabControl mainTabControl)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = Globals.appName + "——打开文档：";
            ofd.Filter = Globals.appName +
                " 文档(*.lpdoc)|*.lpdoc|" + Globals.appName +
                " 模板文档(*.lptemp)|*.lptemp|可移植网络图形(*.png)|*.png|全部支持格式(*.lpdoc;*.lptemp;*.png)|*.lpdoc;*.lptemp;*.png";
            ofd.FilterIndex = 4;
            ofd.Multiselect = true;

            if (Directory.Exists(Globals.pathofUserDocuments) == false)
            {
                Directory.CreateDirectory(Globals.pathofUserDocuments);
            }

            ofd.InitialDirectory = Globals.pathofUserDocuments;

            //只有Vista以上版本才支持。
            if (System.Environment.OSVersion.Version.Major >= 6)
            {
                ofd.CustomPlaces.Add(
                    new FileDialogCustomPlace(Globals.pathofUserDocuments));

                ofd.CustomPlaces.Add(
                    new FileDialogCustomPlace(Globals.pathOfUserTemplateDocuments));
            }

            if (ofd.ShowDialog(Globals.MainWindow) != true)
            {
                window.Focus();
                Globals.SwitchInputMethod(false);
                return;
            }

            if (ofd.FileNames.Count() > 10)
            {
                System.Windows.MessageBoxResult result
                    = System.Windows.MessageBox.Show(
                    "您选择的文件数目大于10个，这可能严重影响程序运行速度。真的要继续吗？",
                    Globals.appName,
                    System.Windows.MessageBoxButton.YesNo,
                    System.Windows.MessageBoxImage.Warning);

                if (result != System.Windows.MessageBoxResult.Yes)
                {
                    window.Focus();
                    Globals.SwitchInputMethod(false);
                    return;
                }
            }

            List<string> filenames = new List<string>();
            foreach (string s in ofd.FileNames)
            {
                filenames.Add(s);
            }

            OpenFile(window, mainTabControl, filenames);
        }

        public static void OpenFile(MainWindow window,
            System.Windows.Controls.TabControl mainTabControl, List<string> filenames)
        {
            Editor editor = null;

            foreach (string filename in filenames)
            {
                if (File.Exists(filename) == false) continue;// 如果文件不存在，跳过。

                string shortname = Editor.GetShortFilenameFromFullname(filename);

                if (filename.EndsWith(".lnk"))
                {
                    MessageBox.Show("【" + shortname + "】不是文件而是快捷方式，无法直接打开！",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    continue;
                }

                if (OpenedAlready(mainTabControl, shortname))
                {
                    MessageBox.Show(
                        "已经打开一个名为：《" + shortname + "》的文件。为防止误操作，"
                    + "不能打开同文件名的文件，——即使这两个文件不在同一目录下。",
                    Globals.appName,
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Warning);
                    continue;
                }

                XmlReader reader = null;

                try
                {
                    editor = new Editor(window);

                    if ((File.GetAttributes(filename) & FileAttributes.ReadOnly) > 0)
                    {
                        editor.IsReadOnly = true;
                    }

                    editor.FileName = filename;

                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.ConformanceLevel = ConformanceLevel.Document;
                    settings.IgnoreWhitespace = true;
                    settings.IgnoreComments = true;
                    reader = XmlReader.Create(/*"file:///" +加这个会出错！！*/ filename, settings);

                    editor.XmlDocument.RemoveAll();

                    if (filename.EndsWith(".png") || filename.EndsWith(".lptemp"))
                    {
                        bool start = false;
                        StringBuilder sb = new StringBuilder();
                        using (StreamReader sr = File.OpenText(filename))
                        {
                            string s = "";
                            while ((s = sr.ReadLine()) != null)
                            {
                                if (start == false)
                                {
                                    if (s.EndsWith("<?Lunar Presentation?>"))
                                    {
                                        start = true;
                                    }

                                    continue;
                                }

                                sb.Append(s);
                            }

                            if (sb.Length <= 0)
                            {
                                MessageBox.Show("这个PNG文件可能不是由本程序导出的图片文件！无法从中获取文档内容。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                return;
                            }

                            editor.XmlDocument.LoadXml(sb.ToString());
                        }
                    }
                    else
                    {
                        System.Xml.XmlNode node = editor.XmlDocument.ReadNode(reader); ;

                        //if (node.Name != "xml")
                        //{
                        //}

                        while (node != null)
                        {
                            editor.XmlDocument.AppendChild(node);
                            node = editor.XmlDocument.ReadNode(reader);
                        }

                        if (editor.XmlDocument.DocumentElement.Name != "Expression")
                        {
                            MessageBox.Show("　　这个文件可能不是由本程序生成的文件！无法从中获取文档内容。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }

                        XmlAttribute attrExType = editor.XmlDocument.DocumentElement.GetAttributeByName("Type");
                        if (attrExType == null || attrExType.Value != "SubPanel")
                        {
                            MessageBox.Show("　　这个文件可能不是由本程序生成的文件！无法从中获取文档内容。",
                                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }
                    }

                    LoadDocumentAttributes(editor);

                    editor.RootPanel.XmlData = editor.XmlDocument.SelectSingleNode("Expression");
                    editor.IsModified = false;// 刚刚打开的文档。

                    // 如果打开异常，就不加入。
                    mainTabControl.Items.Add(editor);

                    Command.UpdateRecentlyFilesList(filename);

                    editor.IsOpened = true;//否则自动定位等功能不起作用。这是防止过快操作造成的问题。
                }
                catch (FileNotFoundException e1)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "指定文件【" + shortname + "】读取异常１。",
                        "异常信息如下：\r\n" + e1.Message,
                        e1.StackTrace,
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Warning);
                    continue;
                }
                catch (UriFormatException e2)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "指定文件【" + shortname + "】读取异常２。",
                        "异常信息如下：\r\n" + e2.Message,
                        e2.StackTrace,
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Warning);
                    continue;
                }
                catch (ArgumentNullException e3)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "指定文件【" + shortname + "】读取异常３。",
                        "异常信息如下：\r\n" + e3.Message,
                        e3.StackTrace,
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Warning);
                    continue;
                }
                catch (NullReferenceException e4)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "指定文件【" + shortname + "】读取异常４。",
                        "异常信息如下：\r\n" + e4.Message,
                        e4.StackTrace,
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Warning);
                    continue;
                }
                catch (System.Xml.XPath.XPathException e5)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "指定文件【" + shortname + "】读取异常５。",
                        "异常信息如下：\r\n" + e5.Message,
                        e5.StackTrace,
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Warning);
                    continue;
                }
                catch (System.Xml.XmlException e6)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "打开文件失败。",
                        "指定文件【" + shortname + "】结构异常，正在打开的文件可能已被破坏，" +
                        "或者该文档并不是由本程序生成的文档。\r\n\r\n" +
                        "★注意：如果文档被导出为png格式的图片文件，可以打开；但Tiff的不能打开！\r\n\r\n" +
                        "异常信息如下：\r\n" + e6.Message,
                        e6.StackTrace,
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Warning);
                    continue;
                }
                finally
                {
                    if (reader != null) reader.Close();
                }
            }

            // editor是最后一个打开的文档。
            if (editor != null && mainTabControl.Items.Contains(editor))
            {
                //editor.ParentWindow.Focus();
                mainTabControl.SelectedIndex
                    = mainTabControl.Items.IndexOf(editor);
                Globals.selectedEditor = editor;

                if (window.scvOfExLayersTree.Visibility != System.Windows.Visibility.Visible)
                {
                    window.EnableStatusControls(System.Windows.Visibility.Visible);
                }

                editor.ListExpressionsTreeOnStatusBar(editor.SelectedExpression);

                Globals.RefreshToolsWhenNewOrOpenDocument(editor.ParentWindow);
                editor.Focus();
            }
        }

        /// <summary>
        /// 载入文档的相关特性。如“自动折行”、“最大文本宽度”、“编辑器默认前景色、背景色”、“页眉”等。
        /// </summary>
        /// <param name="editor"></param>
        private static void LoadDocumentAttributes(Editor editor)
        {

            //读出文档的页面设置信息。
            XmlAttribute attrPageSettingInfo =
                editor.XmlDocument.DocumentElement.GetAttributeByName("PageSettingInfo");
            if (attrPageSettingInfo != null && attrPageSettingInfo.Value.Length > 0)
            {
                editor.PageSettingInfo.SetPageSettings(attrPageSettingInfo.Value);
            }

            //读出文本块是否自动折行。
            System.Xml.XmlAttribute attrAutoWrap =
                editor.XmlDocument.DocumentElement.GetAttributeByName("AutoWrap");
            if (attrAutoWrap != null)
            {
                editor.AutoWrap = bool.Parse(attrAutoWrap.Value);
            }

            //读出“最大文本宽度”
            System.Xml.XmlAttribute attrMaxTextWidth =
                editor.XmlDocument.DocumentElement.GetAttributeByName("MaxTextWidth");
            if (attrMaxTextWidth != null)
            {
                editor.MaxTextWidth = double.Parse(attrMaxTextWidth.Value);
            }

            System.Xml.XmlAttribute attrMaxWidthOfRootPanel =
                editor.XmlDocument.DocumentElement.GetAttributeByName("MaxWidthOfRootPanel");
            if (attrMaxWidthOfRootPanel != null)
            {
                editor.MaxWidthOfRootPanel = attrMaxWidthOfRootPanel.Value;
            }

            //读出编辑器默认前、背景色。

            System.Xml.XmlAttribute attrDefaultExForeground =
                editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultForeground");
            if (attrDefaultExForeground != null)
            {
                editor.DefaultForeground = ColorPicker.GetBrushByName(attrDefaultExForeground.Value);
            }

            System.Xml.XmlAttribute attrDefaultExBackground =
                editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultBackground");
            if (attrDefaultExBackground != null)
            {
                Brush bsh = ColorPicker.GetBrushByName(attrDefaultExBackground.Value);
                if (bsh == null)
                {
                    //可能是图像。
                    string imgDataText = attrDefaultExBackground.Value;
                    System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();

                    if (imgDataText != null && imgDataText.Length > 0)
                    {
                        byte[] b = Convert.FromBase64String(imgDataText);
                        bmp.BeginInit();
                        bmp.StreamSource = new MemoryStream(b);
                        bmp.EndInit();

                        ImageBrush iBsh = new ImageBrush(bmp) { Stretch = System.Windows.Media.Stretch.UniformToFill };
                        iBsh.ViewportUnits = System.Windows.Media.BrushMappingMode.Absolute;
                        iBsh.Viewport = new System.Windows.Rect(0, 0, iBsh.ImageSource.Width, iBsh.ImageSource.Height);

                        System.Xml.XmlAttribute attrTileMode = editor.XmlDocument.DocumentElement.GetAttributeByName("TileMode");
                        if (attrTileMode != null)
                        {
                            iBsh.TileMode = (TileMode)Enum.Parse(typeof(TileMode), attrTileMode.Value);
                        }

                        editor.RefreshDefaultBackgroundWithoutXml(iBsh);
                    }
                    else
                    {
                        editor.BaseScrolledViewer.Background = Brushes.Black;
                    }
                }
                else
                {
                    editor.DefaultBackground = bsh;
                }
            }

            //读取选择框的色彩。
            System.Xml.XmlAttribute attrExSelectionAdornerBrush =
                editor.XmlDocument.DocumentElement.GetAttributeByName("ExSelectionAdornerBrush");
            if (attrExSelectionAdornerBrush != null)
            {
                editor.ExSelectionAdornerBrush = ColorPicker.GetBrushByName(attrExSelectionAdornerBrush.Value);
            }

            System.Xml.XmlAttribute attrSubPanelSelectionAdornerBrush =
                editor.XmlDocument.DocumentElement.GetAttributeByName("SubPanelSelectionAdornerBrush");
            if (attrSubPanelSelectionAdornerBrush != null)
            {
                editor.SubPanelSelectionAdornerBrush = ColorPicker.GetBrushByName(attrSubPanelSelectionAdornerBrush.Value);
            }

            //读取１－４级标题文本块的默认前景色。

            System.Xml.XmlAttribute attrDef1TextClr =
                editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultHeaderText1Color");
            if (attrDef1TextClr != null)
            {
                editor.DefHeaderText1Brush = ColorPicker.GetBrushByName(attrDef1TextClr.Value);
            }
            else
            {
                editor.DefHeaderText1Brush = editor.DefaultForeground;
            }

            System.Xml.XmlAttribute attrDef2TextClr =
                editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultHeaderText2Color");
            if (attrDef2TextClr != null)
            {
                editor.DefHeaderText2Brush = ColorPicker.GetBrushByName(attrDef2TextClr.Value);
            }
            else
            {
                editor.DefHeaderText2Brush = editor.DefaultForeground;
            }

            System.Xml.XmlAttribute attrDef3TextClr =
                editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultHeaderText3Color");
            if (attrDef3TextClr != null)
            {
                editor.DefHeaderText3Brush = ColorPicker.GetBrushByName(attrDef3TextClr.Value);
            }
            else
            {
                editor.DefHeaderText3Brush = editor.DefaultForeground;
            }

            System.Xml.XmlAttribute attrDef4TextClr =
                editor.XmlDocument.DocumentElement.GetAttributeByName("DefaultHeaderText4Color");
            if (attrDef4TextClr != null)
            {
                editor.DefHeaderText4Brush = ColorPicker.GetBrushByName(attrDef4TextClr.Value);
            }
            else
            {
                editor.DefHeaderText4Brush = editor.DefaultForeground;
            }

            //读取出文档的页眉文本。
            System.Xml.XmlAttribute attrPageHeaderLeft =
                editor.XmlDocument.DocumentElement.GetAttributeByName("PageHeaderLeft");
            if (attrPageHeaderLeft != null)
            {
                editor.RefreshPageHeaderLeft(attrPageHeaderLeft.Value);
            }

            System.Xml.XmlAttribute attrPageHeaderMiddle =
                editor.XmlDocument.DocumentElement.GetAttributeByName("PageHeaderMiddle");
            if (attrPageHeaderMiddle != null)
            {
                editor.RefreshPageHeaderMiddle(attrPageHeaderMiddle.Value);
            }

            System.Xml.XmlAttribute attrPageHeaderRight =
                editor.XmlDocument.DocumentElement.GetAttributeByName("PageHeaderRight");
            if (attrPageHeaderRight != null)
            {
                editor.RefreshPageHeaderRight(attrPageHeaderRight.Value);
            }
        }

        /// <summary>
        /// 判断是否有一个同短名称的文件已被打开。
        /// </summary>
        /// <param name="mainTabControl"></param>
        /// <param name="shortname"></param>
        /// <returns></returns>
        private static bool OpenedAlready(System.Windows.Controls.TabControl mainTabControl, string shortname)
        {
            foreach (TabItem ti in mainTabControl.Items)
            {
                Editor e = ti as Editor;

                if (e != null)
                {
                    if (e.FileNameHeader.Text == shortname)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}
